import os
from numpy import full
import pandas as pd
import sys
from pathlib import Path
import re
from datetime import datetime

class BaseClass:
    """根类，提供基础功能和属性，支持读取目录文件夹名称和 Excel 文件内容"""
    def __init__(self):
        print(f'初始化成功')
        """获取资源文件的绝对路径，支持开发环境和打包环境"""
        # if hasattr(sys, '_MEIPASS'):
            # PyInstaller 打包环境，将路径转换为 Path 对象确保跨平台兼容性
            # base_path = Path(sys._MEIPASS)
        # else:
            # 开发环境，将路径转换为 Path 对象确保跨平台兼容性
        # base_path = Path(os.path.dirname(os.path.abspath(__file__)))
        # self.base_dir = base_path
        # print(base_path)

    def parse_date(self, date_str):
        if pd.isna(date_str):
            return pd.NaT
        date_str = str(date_str)
        # 处理14位数字格式（YYYYMMDDHHMMSS）
        if re.match(r'^\d{14}$', date_str):
            try:
                return datetime.strptime(date_str, '%Y%m%d%H%M%S')
            except ValueError:
                pass
        # 处理8位数字+字符格式（提取前8位数字）
        match = re.match(r'^(\d{8})\D*', date_str)
        if match:
            try:
                return datetime.strptime(match.group(1), '%Y%m%d')
            except ValueError:
                pass
        # 处理正常日期格式（自动识别常见格式）
        try:
            return pd.to_datetime(date_str)
        except ValueError:
            return pd.NaT  # 无法解析的日期返回NaT

    def get_data_dir(self, base_dir = 'data'):
        """验证并返回数据文件根目录"""
        # base_dir = Path(base_dir)
        # self.base_path = self.base_dir / base_dir
        self.base_path = Path(base_dir)
        self.base_path.mkdir(parents=True, exist_ok=True)
        return base_dir

    def get_source_dir(self, source_dir):
        """获取资源指定目录"""
        source_dir = self.base_path / source_dir
        print(f'source_dir: {source_dir}')
        source_dir.mkdir(parents=True, exist_ok=True)
        self.source_dir = source_dir
        return source_dir

    
    def get_subdirectories(self, directory_path):
        """获取指定目录下的所有子文件夹名称"""
        subdirectories = []
        # 先构建完整的目录路径
        full_path =  self.source_dir
        print(f'full_path:{full_path}')
        # 检查路径是否存在
        if not full_path.exists():
            print(f"错误: 目录 {full_path} 不存在")
            return subdirectories
        for item in os.listdir(full_path):
            item_path = full_path / item
            if item_path.is_dir():
                subdirectories.append(item)
        return subdirectories

    def verify_file_in_subdirectories(self, directory_path, target_file):
        """验证目录下多个子目录是否存在指定文件

        :param directory_path: 待检查的目录路径
        :param target_file: 要查找的目标文件名
        :return: 如果任一子目录存在目标文件返回 True，否则返回 False
        """
        checkResult = []
        for item in directory_path:
            res = self.verify_file_in_subdirectorie(item, target_file)
            checkResult.append(res)
        return checkResult

    def verify_file_in_subdirectorie(self, directory_path, target_file):
        """验证目目录是否存在指定文件

        :param directory_path: 待检查的目录路径
        :param target_file: 要查找的目标文件名
        :return: 如果任一子目录存在目标文件返回 True，否则返回 False
        """
        item_path = self.source_dir / directory_path
        file_path = os.path.join(item_path, target_file)
        result = False
        if os.path.isdir(item_path):
            if os.path.exists(file_path):
                result = True
        return {directory_path: result}

    """文件读取"""
    def read_excel_files(self, file_dir=None, file_name=None, header_title = [], header_num=0):
        file_path = os.path.join(file_dir, file_name)
        print(f"读取文件中{file_path}")
        if os.path.isdir(file_dir):
            if os.path.exists(file_path):
                df = pd.read_excel(file_path, header=header_num)
                # print(df)
                """保留表格数据中指定字段 """
                if header_title:
                    # print(f'{df.columns.tolist()}')
                    missing_cols = [col for col in header_title if col not in df.columns]
                    if missing_cols:
                        print(f"[DEBUG] 缺少必要列: {missing_cols}，现有列: {df.columns.tolist()}")
                        return []
                    # print(f"[DEBUG] 找到所需列: {header_title}")
                    df = df[header_title]
                return df
            else:
                self.error = '{file_path}文件不存在'
        else:
            self.error = '读取{file_dir}目录不存在'
        return False

    """验证并获取关系数据"""
    def check_data(self, file_name='银行流水数据库.xlsx', source='source'):
        print(f"\n[DEBUG] 开始检查数据")
        print(f"[DEBUG] 当前工作目录: {os.getcwd()}")
        print(f"[DEBUG] DATA_DIR: {self.base_path.absolute()}")
        self.get_source_dir(source)
        print(f"[DEBUG] SOURCE_DIR: {self.source_dir.absolute()}")
        
        # 确保source目录存在
        self.source_dir.mkdir(parents=True, exist_ok=True)
        
        # 遍历source目录下的所有子文件夹
        folders_data = []
        any_found = False

        # 检查source目录是否存在且可访问
        if self.source_dir.exists() and self.source_dir.is_dir():
            print(f"[DEBUG] SOURCE_DIR存在且可访问")
            for folder in self.source_dir.iterdir():
                if folder.is_dir():
                    print(f"\n[DEBUG] 处理文件夹: {folder.name}")
                    asset_file = folder / file_name
                    print(f"[DEBUG] 检查{file_name}文件: {asset_file}")
                    exists = asset_file.exists()
                    if exists:
                        any_found = True
                        print(f"[DEBUG] 找到{file_name}文件: {asset_file}")
                        
                        # 获取亲属关系数据
                        print(f"[DEBUG] 开始获取亲属关系数据")
                        params = {
                            'keep_columns': ['名称', '关系'],
                            'log_prefix': '亲属',
                            'null_check_column': '名称',      # 动态空值检查列
                        }
                        relatives = self.get_relatives_data(folder, '亲属关系.xlsx', params, 1)
                        business_params = {
                            'keep_columns': ['供应商名称'],
                            'log_prefix': '三商',
                            'null_check_column': '供应商名称',      # 动态空值检查列
                            'fixed_value':'三商公司'
                        }
                        business = self.get_relatives_data(folder, '三商清单明细.xlsx', business_params)
                        print(f"[DEBUG] 获取到三商公司数量: {len(business)}")

                        special_params = {
                            'keep_columns': ['名称', '关系'],
                            'log_prefix': '特殊关系人',
                            'null_check_column': '名称',      # 动态空值检查列
                        }
                        special = self.get_relatives_data(folder, '特定关系人.xlsx', special_params)
                        print(f"[DEBUG] 获取到三商公司数量: {len(special)}")
                        
                        folders_data.append({
                            'name': folder.name,
                            'exists': exists,
                            'status': '已存在' if exists else '未找到',
                            'relatives': relatives,
                            'business': business,
                            'special': special,
                        })
                        print(f"[DEBUG] 已添加文件夹数据: {folder.name}, 亲属数量: {len(relatives)}")

        # 如果没有找到任何文件夹，返回特定消息
        if not folders_data:
            print("[DEBUG] 未找到任何数据文件夹")
            return {
                'exists': False,
                'message': '未找到任何数据文件夹，请确保数据文件夹已正确放置在data/source目录下',
                'folders': []
            }

        print(f"[DEBUG] 返回数据: 文件夹数量={len(folders_data)}, 是否找到数据={any_found}")
        return {
            'exists': any_found,
            'message': '已找到资产关系数据' if any_found else '未在任何文件夹中找到资产关系.xlsx',
            'folders': folders_data
        }

    # 获取关联数据  
    def get_relatives_data(self, folder_path, file_name='', params={}, header=0):
        """获取指定文件夹中的亲属关系数据"""
        try:
            # 修正表头行设置，从第0行开始读取表头
            df = self.read_excel_files(folder_path, file_name, params['keep_columns'], header)
            print(f"[DEBUG] Excel{params['log_prefix']}文件读取成功，列名: {df.columns.tolist()}")
            # 添加数据量检查
            if len(df) == 0:
                print(f"[DEBUG] 警告：读取到空数据，检查文件格式和表头设置")
            # 执行动态数据处理
            return self.process_dataframe(df, params)
            # file_path = folder_path / file_name
            # print(f"\n[DEBUG] 尝试读取{file_name}文件: {file_path}")
            
            # if not file_path.exists():
            #     print(f"[DEBUG] 亲属{file_name}不存在: {file_path}")
            #     return []
                
            # # 读取Excel文件，跳过第一行，使用第二行作为列名
            # print(f"[DEBUG] 开始读取Excel文件: {file_path}")
            # df = pd.read_excel(file_path, header=1)
            
            # 只保留名称和关系列
            # if '名称' in df.columns and '关系' in df.columns:
            #     print(f"[DEBUG] 找到名称和关系列")
            #     # 去除名称为空的行
            #     df = df[df['名称'].notna()]
            #     print(f"[DEBUG] 去除空名称后的行数: {len(df)}")
            #     # 去除重复值
            #     df = df.drop_duplicates(subset=['名称'])
            #     print(f"[DEBUG] 去除重复后的行数: {len(df)}")
            #     # 返回处理后的数据
            #     result = df[['名称', '关系']].values.tolist()
            #     print(f"[DEBUG] 返回的亲属数据数量: {len(result)}")
            #     print(f"[DEBUG] 亲属数据示例: {result[:3] if result else '无数据'}")
            # else:
            #     print(f"[DEBUG] 未找到名称或关系列，现有列: {df.columns.tolist()}")
            #     return []
                
        except Exception as e:
            print(f"[DEBUG] 读取{params['log_prefix']}文件出错 {folder_path / file_name}: {str(e)}")
            import traceback
            traceback.print_exc()
            return []

    # 动态数据处理函数
    """
    params = {
        'keep_columns': ['名称', '关系'],  # 动态保留列
        'null_check_column': '名称',      # 动态空值检查列
        'log_prefix': '亲属',             # 日志前缀
        'fixed_value': '系统默认值'       # 新增固定值参数
    }
    """
    def process_dataframe(self, df, params):
        # 动态去除空值
        initial_count = len(df)
        df = df[df[params['null_check_column']].notna() & df[params['null_check_column']].str.strip().ne('')]
        
        # 动态去除重复值
        df = df.drop_duplicates(subset=[params['null_check_column']])
        
        # 动态选择保留列
        result = df.values.tolist()
        
        # 添加固定值
        if 'fixed_value' in params and params['fixed_value'] is not None:
            result = [row + [params['fixed_value']] for row in result]
        
        # 动态日志输出
        print(f"[DEBUG] 数据清洗完成 - 原始: {initial_count}, 去空后: {len(df)}, 去重后: {len(df)}")
        print(f"[DEBUG] 返回{params['log_prefix']}数据 {len(result)} 条，示例: {result[:3] if result else '无数据'}")
        return result